/************************************************************************/
/*	Copyright (C) 1999 RouterWare, Inc.     							*/
/*	Unpublished - rights reserved under the Copyright Laws of the		*/
/*	United States.  Use, duplication, or disclosure by the 				*/
/*	Government is subject to restrictions as set forth in 				*/
/*	subparagraph (c)(1)(ii) of the Rights in Technical Data and 		*/
/*	Computer Software clause at 252.227-7013.							*/
/*	RouterWare, Inc., 3961 MacArthur Blvd. Suite 212, Newport Beach, CA	*/
/************************************************************************/
#if !defined (__RW_DRIVER_MANAGER_IF_H__)
#define __RW_DRIVER_MANAGER_IF_H__
/****************************************************************************************************************************/

typedef UINT RW_PORT_HANDLE;
typedef void* RW_PORT_BINDING_HANDLE;
typedef void* RW_DRIVER_RECEIVE_INDICATE_HANDLE;

#define RW_INVALID_PORT_BINDING_HANDLE		NULL

/****************************************************************************************************************************/
typedef enum RW_DEVICE_DRIVER_TYPE
{
	RW_ETHERNET_DRIVER = 1,
	RW_PPP_DRIVER = 2
} RW_DEVICE_DRIVER_TYPE;
/****************************************************************************************************************************/
typedef struct RW_DEVICE_DRIVER_IF
{
	RW_DEVICE_DRIVER_TYPE					rw_device_driver_type;

	UINT											(*fp_device_driver_get_mtu)(struct RW_DEVICE_DRIVER_IF* p_rw_device_driver_if, 
														RW_PORT_HANDLE port_handle);
	UINT											(*fp_device_driver_get_speed)(struct RW_DEVICE_DRIVER_IF* p_rw_device_driver_if, 
														RW_PORT_HANDLE port_handle);
	/* This function has a *pointer* to the port handle as one of its parameters */
	struct RW_DEVICE_MESSAGE*				(*fp_device_driver_receive)(struct RW_DEVICE_DRIVER_IF* p_rw_device_driver_if, 
														RW_PORT_BINDING_HANDLE* p_rw_port_binding_handle);
	bool											(*fp_device_driver_send)(struct RW_DEVICE_DRIVER_IF* p_rw_device_driver_if, 
														RW_PORT_HANDLE port_handle, 
														struct RW_DEVICE_MESSAGE* p_rw_device_message);	
} RW_DEVICE_DRIVER_IF;
/****************************************************************************************************************************/
typedef struct RW_DRIVER_MANAGER_IF
{	
	RW_DRIVER_RECEIVE_INDICATE_HANDLE 	(*fp_rw_driver_manager_if_register_device_driver) 
														(struct RW_DRIVER_MANAGER_IF* p_rw_driver_manager_if, 
														struct RW_DEVICE_DRIVER_IF* p_rw_device_driver_if, 
														const char* p_device_driver_name);
	bool 											(*fp_rw_driver_manager_if_deregister_device_driver)	
														(struct RW_DRIVER_MANAGER_IF* p_rw_driver_manager_if, 
														struct RW_DEVICE_DRIVER_IF* p_rw_device_driver_if);

	bool 											(*fp_rw_driver_manager_if_device_driver_receive_indicate) 
														(struct RW_DRIVER_MANAGER_IF* p_rw_driver_manager_if,
														RW_DRIVER_RECEIVE_INDICATE_HANDLE rw_driver_receive_indicate_handle);

	RW_PORT_BINDING_HANDLE					(*fp_rw_driver_manager_if_device_driver_port_up) 
														(struct RW_DRIVER_MANAGER_IF* p_rw_driver_manager_if, 
														struct RW_DEVICE_DRIVER_IF* p_rw_device_driver_if,	
														RW_PORT_HANDLE port_handle);
	bool 											(*fp_rw_driver_manager_if_device_driver_port_down) 
														(struct RW_DRIVER_MANAGER_IF* p_rw_driver_manager_if, 
														struct RW_DEVICE_DRIVER_IF* p_rw_device_driver_if, 
														RW_PORT_HANDLE port_handle);
} RW_DRIVER_MANAGER_IF;
/****************************************************************************************************************************/
typedef struct RW_ETHERNET_DRIVER_IF
{
	RW_DEVICE_DRIVER_IF						parent;

	bool (*fp_get_mac_address)				(struct RW_DEVICE_DRIVER_IF* p_rw_device_driver_if, RW_PORT_HANDLE port_handle, 
														BYTE* p_buffer, UINT buffer_size);
} RW_ETHERNET_DRIVER_IF;
/****************************************************************************************************************************/
typedef struct RW_PPP_DRIVER_IF
{
	RW_DEVICE_DRIVER_IF 						parent;

	bool (*fp_get_local_address)			(struct RW_PPP_DRIVER_IF* p_rw_ppp_driver_if, RW_PORT_HANDLE port_handle, IP_ADDRESS*);
} RW_PPP_DRIVER_IF;
/****************************************************************************************************************************/
typedef enum RW_DEVICE_MESSAGE_TYPE
{
	ETHERNET_MESSAGE_TYPE = 1,
	PPP_MESSAGE_TYPE = 2
} RW_DEVICE_MESSAGE_TYPE;
/****************************************************************************************************************************/
typedef enum RW_ENCAPSULATION_TYPE
{
	TYPE2 = 1,
	SNAP = 2
} RW_ENCAPSULATION_TYPE;
/****************************************************************************************************************************/
typedef struct RW_DEVICE_MESSAGE
{
	RW_DEVICE_MESSAGE_TYPE					type;
	RW_PACKET_HANDLE							payload;
} RW_DEVICE_MESSAGE;
/****************************************************************************************************************************/
void rw_device_message_construct (RW_DEVICE_MESSAGE* p_rw_device_message);
void rw_device_message_destruct (RW_DEVICE_MESSAGE* p_rw_device_message);
/****************************************************************************************************************************/
typedef struct RW_ETHERNET_MESSAGE
{
	RW_DEVICE_MESSAGE							parent;
	ETHERNET_PROTOCOL_TYPE					protocol_id;
	UINT											port_number;
	BYTE											source_mac_address[ETHERNET_MAC_ADDRESS_LENGTH];
	BYTE											destination_mac_address[ETHERNET_MAC_ADDRESS_LENGTH];
	RW_ENCAPSULATION_TYPE					encapsulation_type;	
} RW_ETHERNET_MESSAGE;
/****************************************************************************************************************************/
void rw_ethernet_message_construct (RW_ETHERNET_MESSAGE* p_rw_ethernet_message);
void rw_ethernet_message_destruct (RW_ETHERNET_MESSAGE* p_rw_ethernet_message);

RW_ETHERNET_MESSAGE* rw_ethernet_message_create (void);
bool rw_ethernet_message_destroy (RW_ETHERNET_MESSAGE* p_rw_ethernet_message);

bool rw_ethernet_message_serialize (RW_ETHERNET_MESSAGE* p_rw_ethernet_message, RW_PACKET_HANDLE* payload);
bool rw_ethernet_message_deserialize (RW_ETHERNET_MESSAGE* p_rw_ethernet_message, RW_PACKET_HANDLE payload);
/* ************************************************************************************************************************ */
typedef struct RW_PPP_MESSAGE
{
	RW_DEVICE_MESSAGE							parent;
	/* And some more message header fields */
} RW_PPP_MESSAGE;
/****************************************************************************************************************************/
void rw_ppp_message_construct (RW_PPP_MESSAGE* p_rw_ppp_message);
void rw_ppp_message_destruct (RW_PPP_MESSAGE* p_rw_ppp_message);

RW_PPP_MESSAGE* rw_ppp_message_create (void);
bool rw_ppp_message_destroy (RW_PPP_MESSAGE* p_rw_ppp_message);

bool rw_ppp_message_serialize (RW_PPP_MESSAGE* p_rw_ppp_message, RW_PACKET_HANDLE* payload);
bool rw_ppp_message_deserialize (RW_PPP_MESSAGE* p_rw_ppp_message, RW_PACKET_HANDLE payload);
/* ************************************************************************************************************************ */
#endif /* __RW_DRIVER_MANAGER_IF_H__ */
